package com.kedou.net;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import android.os.AsyncTask;

import com.kedou.app.Config;
import com.kedou.util.DebugUtil;
import com.kedou.util.Util;

/**
 * 通信的基类
 * 
 * @author zhouchao
 * 
 */
public class NetConnection {

	public NetConnection(final String url, final HttpMethod method,
			final SuccessCallback successCallback,
			final FailCallback failCallback, final String... kvs) {

		new AsyncTask<Void, Void, String>() {

			@Override
			protected String doInBackground(Void... arg0) {
				DebugUtil.printE("url", url);
				String[] newKvs = new String[kvs.length + 4];
				for (int i = 0; i < kvs.length; i++) {
					newKvs[i] = kvs[i];
				}
				// 加上参数:t=时间戳以及team=对应密钥
				newKvs[newKvs.length - 1] = Config.KEY_HTTP;
				newKvs[newKvs.length - 2] = Config.KEY_TEAM;
				newKvs[newKvs.length - 3] = String.valueOf(System
						.currentTimeMillis());
				newKvs[newKvs.length - 4] = Config.KEY_T;
				String sig = getSig(newKvs);
				StringBuffer paramsStr = new StringBuffer();
				for (int i = 0; i < kvs.length; i += 2) {
					paramsStr.append(kvs[i]).append("=").append(kvs[i + 1])
							.append("&");
				}
				paramsStr.append(Config.KEY_SIG).append("=").append(sig);
				DebugUtil.printE("最终参数列表", paramsStr.toString());
				try {
					URLConnection uc;
					switch (method) {
					case POST:
						uc = new URL(url).openConnection();
						uc.setDoOutput(true);
						BufferedWriter bw = new BufferedWriter(
								new OutputStreamWriter(uc.getOutputStream(),
										Config.ENCODING));
						bw.write(paramsStr.toString());
						bw.flush();
						break;
					default:
						uc = new URL(url + "?" + paramsStr.toString())
								.openConnection();
						break;
					}
					DebugUtil.printE("Request url", uc.getURL().toString());
					DebugUtil.printE("Request data", paramsStr.toString());
					BufferedReader br = new BufferedReader(
							new InputStreamReader(uc.getInputStream(),
									Config.ENCODING));
					String line = null;
					StringBuffer result = new StringBuffer();
					while ((line = br.readLine()) != null) {
						result.append(line);
					}
					return result.toString();

				} catch (MalformedURLException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}

				return null;
			}

			@Override
			protected void onPostExecute(String result) {
				DebugUtil.printE("response data", result);
				if (result != null && !result.equals("null")) {
					if (successCallback != null) {
						DebugUtil.printE("访问网络", "成功");
						successCallback.onSuccess(result);
					}
				} else {
					if (failCallback != null) {
						DebugUtil.printE("访问网络", "失败");
						failCallback.onFail();
					}
				}

				super.onPostExecute(result);
			}
		}.execute();

	}

	public static interface SuccessCallback {
		void onSuccess(String result);
	}

	public static interface FailCallback {
		void onFail();
	}

	/**
	 * 根据约定的加密规则对参数进行加密
	 * 
	 * @param kvs
	 *            要加密的参数数组
	 * @return sig即签名
	 */
	private String getSig(String... kvs) {
		ArrayList<String> keys = new ArrayList<String>();
		StringBuffer paramsStr = new StringBuffer();
		Map<String, String> map = new HashMap<String, String>();
		for (int i = 0; i < kvs.length; i += 2) {
			keys.add(kvs[i]);
			map.put(kvs[i], kvs[i + 1]);
		}
		// 对key按字典升序排列
		Collections.sort(keys);
		// 升序后的key，按照key=value以"&"拼接起来
		for (int j = 0; j < keys.size(); j++) {
			map.get(keys.get(j));
			paramsStr.append(URLEncoder.encode(keys.get(j))).append("=")
					.append(URLEncoder.encode(map.get(keys.get(j))))
					.append("&");
		}
		// 去掉最后一个&
		if (paramsStr != null) {
			paramsStr = paramsStr.delete(paramsStr.length() - 1,
					paramsStr.length());
		}
		DebugUtil.printE("sig之前，排序之后key=value", paramsStr.toString());
		String sig = null;
		try {
			byte[] hmacSHA1 = Util.HmacSHA1(paramsStr.toString(),
					Config.KEY_HTTP);
			sig = hmacSHA1.toString();
			DebugUtil.printE("sig", sig);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		return sig;
	}
}
